<template>

  <el-container class="layout-container-demo" style="height: 97.5vh">
    
    <el-aside  id="aside"  :style="{ width: asideWidth + 'px'}" >   <!-- 动态限制宽度,加了就会有下拉的箭头 -->
       <el-scrollbar >   <!-- 侧边栏滑动条 --> 
    
           <el-menu v-for="(item,menu) in menuItems " :default-active="activeIndex" class="el-menu-vertical-demo"     active-text-color="#ffd04b"  :collapse="isCollapse" :collapse-transition="false" > <!--:collapse-transition="false" 关掉折叠过度效果,也可以自定义-->
            <!-- 菜单组 -->
            <el-sub-menu  :index="item.menuindex" :key="item.menuindex " v-if="item.menu"  >
                <template #title >
                  <el-icon >
                    <component :is="item.iconClass" /> <!--  动态显示图标 -->
                  </el-icon>
                  <span>  {{ item.label }}</span>
              </template>

             <!-- 子菜单栏 -->
                  <template v-for="child in menuItems"  >
                  <el-sub-menu :index="child.menuindex" :key="child.menuindex"   v-if="child.parent==item.menuindex && child.submenu"  >
                    <template #title >
                    <el-icon  >
                    <component :is="child.iconClass" />  <!--  动态显示图标  -->
                  </el-icon>
                    <span>  {{ child.label }}</span>
                      </template>
                      <!-- 三级子菜单 -->
                      <template v-for="child1 in menuItems" >
                      <el-menu-item :index="child1.menuindex" :key="child1.menuindex" @click=" addTabs(child1)"    v-if="child1.parent==child.menuindex "  >
                        <el-icon  >
                        <component :is="child1.iconClass" />    
                      </el-icon>
                        {{ child1.label }}
                      </el-menu-item>
                        </template> 
                  </el-sub-menu>
                </template>
               
              <!-- 二级子菜单 -->
                  <template v-for="child in menuItems" >
                  <el-menu-item :index="child.menuindex" :key="child.menuindex" @click="addTabs(child)" v-if="child.parent==item.menuindex && !child.submenu "  >
                    <el-icon  >
                    <component :is="child.iconClass" />  <!--   动态显示图标   -->
                  </el-icon>
                    {{ child.label }}
                  </el-menu-item>
              </template>  
      </el-sub-menu>
    </el-menu>
      </el-scrollbar>
    </el-aside>
    <el-container>
      
      <!-- 头部显示区域 -->
      <el-header style="text-align: left; font-size: 15px;   " >
        <div > 
          <div style=" float: left; height: 50px;  line-height: 50px; margin-left: 10px;">
            <el-radio-group v-model="isCollapse"  >
            <el-radio-button :value="false"@click="zhank()">展开</el-radio-button>
            <el-radio-button :value="true" @click="zhed()">折叠</el-radio-button>
            </el-radio-group> 
        </div>

        <div style=" float: right; height: 50px;  line-height: 50px; margin-right: 20px; ">
        <!-- 全屏按钮 -->
                  <el-button type="text" @click="toggleFullscreen" style="margin-right: 15px;">
                      <el-icon :size="25" color="#39587E">
                        <component :is="isFullscreen ? Aim : FullScreen" />
                      </el-icon>
                    </el-button>

                      <el-dropdown style="text-align: right; font-size: 20px; ">
                      <!-- 头像 -->
                      <el-avatar :size="30" :src="avatarUrl" style="margin-top: 35%; "  />

                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item @click="logout">注销</el-dropdown-item>
                          <el-dropdown-item @click="logout">退出</el-dropdown-item>
                          <el-dropdown-item @click="openDialog">更换头像</el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                    <!-- 用户名 -->
                    <span style="margin-left: 20px; font-size: 18px; " >{{ username }}</span>
                </div>
        </div>
      </el-header>

<!-- 上传头像的对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="修改头像"
      width="20%" 
      height = auto
      :before-close="handleClose"
    >
      <!-- 图片上传组件 -->
      <el-upload
        class="avatar-uploader"
        action="#" 
        :show-file-list="true"
        :on-change="handleFileChange"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload"
      >
        <!-- 图片预览 -->
        <img v-if="imageUrl" :src="imageUrl" class="avatar-preview" style="width: 100%; height: 100%;" />
        <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
      </el-upload>

      <!-- 对话框底部按钮 -->
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitAvatar">确认</el-button>
        </span>
      </template>
    </el-dialog>


      <!-- 主页面显示区域 -->
      <el-main style="background-color: white;">
          <!-- 标签栏 -->
          <el-tabs
            v-model="editableTabsValue"
            type="card"
            closable
            class="demo-tabs"
            @edit="handleTabsEdit"
            @contextmenu.prevent="openMenu"
             @click="handleOutsideClick"
          >
          <el-tab-pane
            v-for="item in editableTabs"
            :key="item.name"
            :label="item.title"
            :name="item.name"
          >
          <keep-alive>
          <router-view :v-if=isRouteLoaded :name=item.router></router-view>  
        </keep-alive>
          </el-tab-pane>

           <ul v-show="visible" :style="{left: left + 'px', top: top + 'px'}" class="contextmenu">
            <li @click="closeTabsOnRight">关闭右侧</li>
            <li @click="closeTabsOnLeft">关闭左侧</li>
            <li @click="closeOtherTabs">关闭其它</li>
            <li @click="closeAllTabs">关闭所有</li>
          </ul>

  </el-tabs>
  
      </el-main>
    </el-container> 
  </el-container>
</template> 

<script lang="ts" setup>
import { ref,reactive,onMounted,computed, } from 'vue'
// npm install @element-plus/icons-vue 图标全局安装命令
import { Menu as IconMenu, Setting, User, HelpFilled,ChatLineRound,House,Pointer,ChatLineSquare } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router';   // npm install vue-router@4  没有的话安装下
import { RouterView } from 'vue-router';  
import { type TabPaneName,ElMessage } from 'element-plus'
import screenfull from'screenfull'; // 引入 screenfull 库  npm install screenfull
import request from './utils/request';
import { Aim, FullScreen } from '@element-plus/icons-vue';
const router = useRouter(); // 获取路由
const isCollapse = ref(false); //控制菜单栏的展开折叠变量
const activeIndex = ref('1');
let asideWidth = ref(200); // 侧边栏的宽度 
const isRouteLoaded = ref(true);  //

const username = ref('用户名');// 用户名
const visible = ref(false); //
const left = ref(0);
const top = ref(0);
const avatar = ref('');

// 头像的 URL
const avatarUrl = ref(''); // 默认头像
const imageUrl = ref(''); // 上传后的图片预览 URL
const dialogVisible = ref(false); // 控制对话框显示
const file = ref(null); // 选择的文件


const isFullscreen = ref(false); // 新增：用于跟踪全屏状态

// 新增：切换全屏的方法
const toggleFullscreen = () => {
  if (screenfull.isEnabled) {
    screenfull.toggle().then(() => {
      isFullscreen.value = screenfull.isFullscreen;
    }).catch((err) => {
      console.error('Error while toggling fullscreen:', err);
    });
  }
};


//点击标签栏以为的地方隐藏关闭左边或者右边的标签
const handleOutsideClick = (event) => {
  if (event.target.tagName!== 'BUTTON') {
    visible.value = false;
  }
};

// 打开菜单函数
const openMenu = (event:any, tab:any) => {
  event.preventDefault();  //‌阻止表单的自动提交‌：当表单尝试提交时，使用preventdefault()可以阻止表单的默认提交行为，从而可以进行自定义的验证或其他处理
  visible.value = true;
  left.value = event.clientX-200;
  top.value = event.clientY-105;
};

  // 设置路由前置守卫
  router.beforeEach((to, from, next) => {
    debugger;
      if (to.matched.length === 0) {
        // 路由不匹配，不进行重置
        next(false);
      } else {
        // 路由匹配，正常跳转
        next();
      }
    });

    // 注销和退出的处理函数
const logout = () => {
  // 清除本地存储中的令牌和用户信息
  localStorage.removeItem('token');
  localStorage.removeItem('userInfo');

  // 跳转到登录页面
  router.push('/Login');

  // 可以添加提示信息
  ElMessage.success('已成功退出登录');
};

//点击菜单栏编辑标签栏数组
function addTabs(child:any){
  const newTabName = `${++tabIndex}`
    editableTabs.value.push({
      title: child.label,
      name: newTabName,
      router: child.router,
    })
    editableTabsValue.value = newTabName;
    router.push("/main/home");   // 总路由
}

// 定义用于关闭左侧标签的函数
const closeTabsOnLeft = () => {
  const currentIndex = editableTabs.value.findIndex(tab => tab.name === editableTabsValue.value);
  if (currentIndex!== -1) {
    // 过滤出要保留的标签，即当前标签及右侧的标签
    const remainingTabs = editableTabs.value.filter((_, index) => index >= currentIndex);
    editableTabs.value = remainingTabs;
  }
};

// 定义一个函数用于处理关闭右侧标签的操作
const closeTabsOnRight = () => {
  const currentIndex = editableTabs.value.findIndex(tab => tab.name === editableTabsValue.value);
  if (currentIndex!== -1) {
    // 过滤出要保留的标签，也就是当前标签及左侧的标签
    const remainingTabs = editableTabs.value.filter((_, index) => index <= currentIndex);
    editableTabs.value = remainingTabs;
  }
};

// 定义用于关闭其他标签（除当前激活标签外）的函数
const closeOtherTabs = () => {
  const currentIndex = editableTabs.value.findIndex(tab => tab.name === editableTabsValue.value);
  if (currentIndex!== -1) {
    // 通过过滤，只保留当前激活的标签
    const remainingTabs = editableTabs.value.filter(tab => tab.name === editableTabsValue.value);
    editableTabs.value = remainingTabs;
  }
};

// 定义用于关闭所有标签的函数
const closeAllTabs = () => {
  // 直接将editableTabs.value赋值为空数组，清空所有标签数据
  editableTabs.value = [];
};

// 钩子函数，在页面初始化的时候清空标签栏默认的空数组
onMounted(() => {
  editableTabs.value = [];
});
 

//折叠控制边框宽度
function zhed(){
  asideWidth.value = 60;
}

 //折叠控制边框宽度
 function zhank(){
  asideWidth.value = 200;
}

//获取sessionStorage中的菜单数据数据 动态渲染菜单
let menuItems = ref(computed(() => {
  debugger;
      const storedMenu = sessionStorage.getItem('menuData');
      const data = storedMenu ? JSON.parse(storedMenu) : [];
      const ava = sessionStorage.getItem('avatarUrl');
      const user = sessionStorage.getItem('user');
      const users = user ? JSON.parse(user) : [];
      username.value = users.realname;
      if(ava!==null){
        avatarUrl.value = ava;
        imageUrl.value = ava;
      }else{ 
        avatarUrl.value = users.avatar;
        imageUrl.value = users.avatar; 
      }
     
      return convertStringsToBooleans(data);
      
    }));

//获取sessionStorage中的菜单数据数据 动态渲染菜单
let user = ref(computed(() => {
      debugger;
      const user = sessionStorage.getItem('user');
      const data = user ? JSON.parse(user) : [];
      return  data;
    }));

  // 递归函数，将字符串 "true" 和 "false" 转换为布尔值
function convertStringsToBooleans(data) {
  if (Array.isArray(data)) {
        // 如果是数组，递归处理每个元素
        return data.map(item => convertStringsToBooleans(item));
    } else if (data !== null && typeof data === 'object') {
        // 如果是对象，递归处理每个键值对
        const result = {};
        for (const key in data) {
            if (data[key] === "true") {
                result[key] = true;
            } else if (data[key] === "false") {
                result[key] = false;
            } else {
                result[key] = convertStringsToBooleans(data[key]);
            }
        }
        return result;
    }
    // 如果是基本类型，直接返回
    return data;
}
 
// 标签栏数据
let tabIndex = 2
const editableTabsValue = ref('1')
const editableTabs = ref([
  {
    title: '',
    name: '',
    router: '',
  },  
])

// 标签增加和删除事件，目前只用删除功能
const handleTabsEdit = (
  targetName: TabPaneName | undefined,
  action: 'remove' | 'add'
) => {
  if (action === 'add') {
    const newTabName = `${++tabIndex}`
    editableTabs.value.push({
      title: 'New Tab',
      name: newTabName,
      router: 'New Tab content',
    })
    editableTabsValue.value = newTabName
  } else if (action === 'remove') {
    const tabs = editableTabs.value
    let activeName = editableTabsValue.value
    if (activeName === targetName) {
      tabs.forEach((tab, index) => {
        if (tab.name === targetName) {
          const nextTab = tabs[index + 1] || tabs[index - 1]
          if (nextTab) {
            activeName = nextTab.name
          }
        }
      })
    }
    editableTabsValue.value = activeName
    editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
  }
}

// 打开对话框
const openDialog = () => {
  dialogVisible.value = true;
};

// 关闭对话框
const handleClose = () => {
  dialogVisible.value = false;
};

// 图片上传成功回调
const handleAvatarSuccess = (file) => {
  debugger;
  imageUrl.value = file.raw;
  //imageUrl.value = URL.createObjectURL(file.raw); // 生成预览 URL
};

// 文件选择回调
const handleFileChange = (uploadFile) => {
  debugger;
  file.value = uploadFile.raw;
  handleUpload();
};

// 图片上传前的校验
const beforeAvatarUpload = (file) => {
  const isImage = file.type.startsWith('image/');
  const isLt8M = file.size / 1024 / 1024 < 8;

  if (!isImage) {
    ElMessage.error('只能上传图片文件！');
  }
  if (!isLt8M) {
    ElMessage.error('图片大小不能超过 8MB！');
  }

  return isImage && isLt8M;
};

/**
 * 处理文件上传的异步函数
 * 此函数首先检查是否有文件被选择，如果没有，则显示警告消息
 * 如果有文件被选择，它将创建一个FormData对象，将文件附加到该对象中，并发送POST请求以上传文件
 * 在文件上传成功后，它将处理响应数据，在失败时显示错误消息
 */
const handleUpload = async () => {
  if (!file.value) {
    ElMessage.warning('请先选择文件');
    return;
  }

  const formData = new FormData();
  formData.append('file', file.value);
  debugger;
  try {
    const response = await request.post('/file/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    imageUrl.value = response.data; // 假设后端返回文件地址
    // ElMessage.success('文件上传成功！');
    // errorMessage.value = '';
  } catch (error) {
    ElMessage.error('文件上传失败');
  }
};

// 提交头像
const submitAvatar = async () => {
  debugger;
  if (imageUrl.value) {

    avatarUrl.value = imageUrl.value; // 更新头像
     
    const response = await  request.post('/sys/user/updateAvatar', { avatar: imageUrl.value,id: user.value.id })
    sessionStorage.setItem('avatarUrl',imageUrl.value );
    ElMessage.success(response.data.message);
    dialogVisible.value = false; // 关闭对话框
  } else {
    ElMessage.warning("头像更新失败");
  }
};


</script>

<style scoped>

.contextmenu {
  margin: 0;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 12px;
  color: #333;
}
.contextmenu li {
  margin: 0;
  padding: 7px 16px;
  cursor: pointer;
}
.contextmenu li:hover {
  background: #eee;
}

.layout-container-demo .el-header {
  position: relative;
 /* 头部图片 */
  background-image: url('/src/assets/head.jpg'); /* 添加背景图片 */
  background-size: cover; /* 背景图片覆盖整个容器 */
  background-position: center; /* 背景图片居中 */
  background-repeat: no-repeat; /* 背景图片不重复 */

}

.layout-container-demo .el-aside {
  color: var(--el-text-color-primary);
  background: var(--el-color-primary-light-8);
}
.layout-container-demo .el-menu {
  border-right: none;
}
.layout-container-demo .el-main {
  padding: 0;
  border-left: 1px solid #ccc;
  /* 头部图片 */
  /* background-image: url('/src/assets/main.jpg'); 添加背景图片 */
  background-size: cover; /* 背景图片覆盖整个容器 */
  background-position: center; /* 背景图片居中 */
  background-repeat: no-repeat; /* 背景图片不重复 */
}
.layout-container-demo .toolbar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  right: 20px;
  width: auto;
}

.avatar-upload-container {
  text-align: center;
  margin-top: 20px;
}

.avatar {
  cursor: pointer;
  border: 2px solid #ddd;
  transition: border-color 0.3s;
}

.avatar:hover {
  border-color: #409eff;
}

.avatar-uploader {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  width: 100%;
  height: 200px;
  overflow: hidden;
}

.avatar-uploader:hover {
  border-color: #409eff;
}

.avatar-preview {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
}

 
 
 
</style>
